<?php
namespace App\Components\Admin;

use App\Components\Admin\Node;
use App\Components\Admin\Router;
use App\Models\System\SystemRole;
use App\Models\System\SystemRoleUser;
use App\Models\System\SystemUser;
use Exception;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;

class AuthVerification
{
    public function __invoke(Request $request, RequestHandler $handler): Response
    {
        $adminPattern = Router::getCurrentRequestControllerInfo();
        if (!isset($adminPattern[2]) || isset($adminPattern[3])) {
            $response = $handler->handle($request);

            return $response;
        }

        $nodeRs = Node::availableNode();
        $isAuth = false;
        foreach ($nodeRs as $v1) {
            if ($v1['node'] != $adminPattern[1]) {
                continue;
            }
            if (!isset($v1['children'])) {
                continue;
            }
            foreach ($v1['children'] as $v2) {
                if ($v2['node'] != $adminPattern[2]) {
                    continue;
                }
                $isAuth = true;
                break 2;
            }
        }
        unset($nodeRs);
        if ($isAuth === false) {
            $response = $handler->handle($request);

            return $response;
        }
        unset($isAuth);

        $userId = SystemUser::getIdByToken();
        if ($userId <= 0) {
            $response = new Response();
            $response = $response->withStatus(302)->withHeader(
                'Location',
                Router::URL_PREFIX . '/index/login?redirect=' . urlencode($adminPattern[0])
            );
            return $response;
        }

        $roleRs = SystemRoleUser::userRole($userId);
        $nodeRs = [];
        foreach ($roleRs as $v) {
            $nodeRs = array_merge($nodeRs, SystemRole::node($v));
        }
        unset($roleRs);
        $nodeRs = array_values(array_unique($nodeRs));
        if (!in_array($adminPattern[1] . ':' . $adminPattern[2], $nodeRs)) {
            throw new Exception('未授权');
        }
        unset($nodeRs, $userId, $adminPattern);

        $response = $handler->handle($request);

        return $response;
    }
}
